home *** CD-ROM | disk | FTP | other *** search
- /*
- SimpleInMovies
-
- Sample programs demonstrating how to open and display
- QuickTime™ Movies.
-
- SimpleInWindows.c file contains the code for the routines
- having to do with creating closing a maintaining movie windows.
-
- Guillermo A. Ortiz
- Macintosh Developer Technical Support
-
- 08/07/91 Created the file to move in the window calls. Also added code to save
- the movie on closing if changes have been made.
-
- 08/22/91 -- Added the code to accomodate the fact that the bounds for the controller now enclose the whole movie.
- 11/19/91 -- Fixed movie saving code to save correctly after saving as...
- 11/21/91 -- Finished the flattening code including the progress stuff.
-
- 10/08/92 -- Added code to check/save the LOOP atom in the user data.
- 10/09/92 -- Added code to check/save the WLOC atom used to store the last position of the movie
- */
-
- #include <SimpleInMovie.h>
-
- extern Component movieControllerComponent;
- extern long gFlattenMovies;
-
- /* ************************************************************************* */
- /* Procedures that handle window stuff */
-
- Boolean CreateOneWindow(Movie, StandardFileReply, short, short);
- Boolean IsAppWindow(WindowPtr);
- Boolean DisposeAllWindows(void);
- Boolean DisposeOneWindow(WindowPtr, short);
- Boolean SaveMovie( DocRecHandle, short);
- Boolean DoSave(short);
- OSErr PutMovieToFile(DocRecHandle, Boolean);
-
- extern DialogPtr GetCenteredDialog(short, WindowPtr, WindowPtr);
- extern void OutlineDialogItem(DialogPtr, short);
- extern pascal Boolean keyEquivFilter(DialogPtr, EventRecord *, short *);
- extern Boolean DisplayPutFile(StandardFileReply *);
- extern Rect CenterWindow(WindowPtr, WindowPtr);
- extern OSErr FixMovieWindow(WindowPtr window);
- extern short GetFileLoopState(DocRecHandle DocHandle);
- extern void SetLoopState(DocRecHandle wHndl);
- extern short GetCurrentLoopState(DocRecHandle wHndl);
- extern void UpdateLoopStateInfo(DocRecHandle wHndl);
- extern void FixWindowPosition(WindowPtr w,DocRecHandle wHndl);
- extern Boolean WPositionChanged(WindowPtr w,DocRecHandle DocHandle);
- extern void UpdateWindowPos(void);
-
- extern short gUntitledCount;
-
- /* opens a window for the movie and the record that keeps the movie playing
- in the window as well as the instance for the player */
- Boolean CreateOneWindow(moov, fileInfo, fileResNum, moovResID)
- Movie moov;
- StandardFileReply fileInfo;
- short fileResNum;
- {
- WindowPtr myWindow;
- Rect moovBox;
- DocRecHandle DocHandle;
- MovieController localController;
- Point where;
- OSErr err;
- Boolean emptyBox = false;
-
- /* Get our display window.
- */
- myWindow = GetNewCWindow(windowID, nil, (WindowPtr) -1);
-
- if ( myWindow && (DocHandle = (DocRecHandle)NewHandle(sizeof(DocRec))) ) { /* get storage for */
- (*DocHandle)->wMovie = moov; /* movie */
- (*DocHandle)->wFileInfo.sfr = fileInfo; /* file */
- (*DocHandle)->wFileInfo.resFile = fileResNum;
- (*DocHandle)->wFileInfo.moovID = moovResID;
- (*DocHandle)->loopState = noLoop; /* default */
-
- if ( localController = OpenComponent((Component)movieControllerComponent) ) { /* and component */
- (*DocHandle)->wPlayer = localController; /* OpenComponent can move memory so it may not a good idea to dereference the handle in the same line */
- SetWRefCon(myWindow, (long)DocHandle);
-
- /* now size window adding some space at the bottom for controller */
- GetMovieBox(moov,&moovBox); /* Use the movie box to resize window */
-
- where.h = moovBox.left;
- where.v = moovBox.top;
-
- if (err = MCNewAttachedController((*DocHandle)->wPlayer, moov, myWindow, where) )
- DebugStr("\pError at PTNewAttachedController");
-
- /* now we resize the window according to the controller settings and the
- dimensions of the movie.
- */
- FixMovieWindow(myWindow);
-
- SetWTitle(myWindow,fileInfo.sfFile.name);
-
-
- SetPort(myWindow);
-
- /* Before we play the movie check the state of looping an set it accordingly */
-
- if (fileResNum != kNoFileOpen) { /* the movie is not brand new */
- (*DocHandle)->loopState = GetFileLoopState(DocHandle);
- if ((*DocHandle)->loopState)
- SetLoopState(DocHandle);
- /* since we are here we can position the window according to the WLOC atom */
- FixWindowPosition(myWindow, DocHandle);
-
- }
-
- ShowWindow(myWindow);
- SelectWindow(myWindow);
-
- if (err = MCDoAction((*DocHandle)->wPlayer, mcActionPlay, (Ptr)0x00010000) )
- DebugStr("\pError at MCGetControllerBoundsRect");
-
- return true;
- }
- }
- /* something failed so we have to get rid of the window */
- DisposeWindow(myWindow);
- return(false);
- }
-
- /* returns true if all windows have been closed */
- Boolean DisposeAllWindows(void)
- {
- WindowPtr window;
-
- while (window = *(WindowPtr *)WindowList) {
-
- /* While we have a front window, try closing it. */
-
- if (!DisposeOneWindow(window, quitCommand)) return(false);
- }
-
- return(true);
- }
-
-
- /* Closes one window */
-
- Boolean DisposeOneWindow(window, command)
- WindowPtr window;
- short command;
- {
- DocRecHandle wHndl;
-
- if (IsAppWindow(window)) {
- if (wHndl = (DocRecHandle)GetWRefCon(window)) { /* Get the storage handle */
- if (SaveMovie(wHndl, command) )
- return (false); /* who knows the user hit cancel maybe */
-
- /***** MCRemoveMovie goes away.
- MCRemoveMovie((*wHndl)->wPlayer);
- */
- CloseComponent((*wHndl)->wPlayer); /* and player instance */
- DisposeMovie((*wHndl)->wMovie); /* and get rid of movie */
- if ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum != kInvalVRefNum) {
- if (CloseMovieFile((*wHndl)->wFileInfo.resFile) )/* file open, close it */
- DebugStr("\pCloseMovieFile failed in DisposeOneWindow");
- }
- DisposHandle((Handle)wHndl); /* and finally the handle */
- }
- }
- DisposeWindow(window);
- return(true);
- }
-
- Boolean IsAppWindow(window)
- WindowPtr window;
- {
- if (window)
- return (((WindowPeek)window)->windowKind >= userKind);
- else
- return false;
- }
- /* *************************************************************** */
-
- /* checks that there is a movie associated with the front most window
- and tries to save it; this is used when the save or save as commands
- are executed.
-
- */
- Boolean DoSave(command)
- short command;
- {
- WindowPtr window;
- DocRecHandle wHndl;
- short volume;
-
- if (window = FrontWindow()) { /* don't bother if no movies to play */
- if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
- if (WPositionChanged(window, wHndl) ) { /* dirty the movie to save the position of the window */
- volume = GetMoviePreferredVolume((*wHndl)->wMovie);
- SetMoviePreferredVolume((*wHndl)->wMovie, volume+1);
- SetMoviePreferredVolume((*wHndl)->wMovie, volume);
- }
- return SaveMovie(wHndl, command);
- }
- }
- }
-
- /* The progress proc lets the user know what is going on while a FlattenMovie call
- is being done.
- Not from MacShell.
- */
- pascal OSErr flattenProgressProc(Movie m, short message, short operation, Fixed percent, long refCon)
- {
- #pragma unused (m)
-
- WindowPtr pDialog;
- Fixed percentFix = 0x00640000; /* hundred in fixed */
- short percentShort;
- Rect windRect,
- progressRect= {100,20,120,200};
- GrafPtr oldPort;
-
- if (operation != progressOpFlatten) /* This should only be called for flatten */
- return featureUnsupported;
- else /* OK this I know about */
- switch (message) {
- case movieProgressOpen:
- SetRect(&windRect,20,20,240,200);
- pDialog = NewCWindow(nil,&windRect,"",false, dBoxProc, (WindowPtr)-1L,true,0);
- CenterWindow(pDialog, nil);
- if (pDialog) {
- GetPort(&oldPort);
- ShowWindow(pDialog);
- SetPort(pDialog);
- MoveTo(30,50);
- DrawString("\pFlattening in progress …");
- FrameRect(&progressRect);
- *(WindowPtr *)refCon = pDialog;
- SetPort(oldPort);
- return noErr;
- }
- break;
- case movieProgressUpdatePercent:
- GetPort(&oldPort);
- SetPort(*(WindowPtr *)refCon);
- percentFix = FixMul(percent, percentFix);
- percentShort = FixRound(percentFix);
- FrameRect(&progressRect);
- InsetRect(&progressRect,2,2);
- progressRect.right = progressRect.left+((progressRect.right - progressRect.left) * percentShort/100);
- PaintRect(&progressRect);
- SetPort(oldPort);
- return noErr;
- break;
- case movieProgressClose:
- DisposeWindow(*(WindowPtr *)refCon);
- return noErr;
- break;
- }
- }
-
-
- /* The next procedures come from the DTS sample MacShell, check it out for more details or
- better comments. Note though that I have modified the code to accomodate the immediate
- needs, don't blame MacShell. */
-
-
- /* checks is the movie has to be saved and depending on the command that
- originated the requests saves the movie.
- */
-
- Boolean SaveMovie( wHndl, command)
- DocRecHandle wHndl;
- short command;
- {
- Str255 closeOrQuit;
- short item;
- StandardFileReply reply;
- OSErr err;
- DialogPtr saveDialog;
-
- if (command != saveMovieAs) { /* If regular save... */
- if (!HasMovieChanged((*wHndl)->wMovie)) { /* If movie clean... */
- /*except that looping could have changed. */
- if ( (*wHndl)->loopState == GetCurrentLoopState(wHndl) )
- return(noErr); /* Consider it saved. */
- }
- }
-
- if ((command == closeMovie) || (command == quitCommand)) {
- /* If implicit save... */
-
- GetIndString(closeOrQuit, rMiscStrings,
- (command == closeMovie) ? sClosing : sQuitting);
- ParamText((*wHndl)->wFileInfo.sfr.sfFile.name, closeOrQuit, nil, nil);
-
- saveDialog = GetCenteredDialog(rYesNoCancel, nil, (WindowPtr)-1L);
-
- if (saveDialog) {
- OutlineDialogItem(saveDialog, kSaveYes);
- ModalDialog((ModalFilterProcPtr)keyEquivFilter, &item);
- DisposDialog(saveDialog);
- }
- else
- item = kSaveYes;
-
- if (item != kSaveYes) {
- err = noErr;
- if (item == kSaveCanceled) err = userCanceledErr;
- return(err);
- }
- }
-
- if (((command == saveMovieAs) ||
- ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum == kInvalVRefNum) )) {
- /* Prompt with SFGetFile if doing a Save As or have never saved before. */
-
- reply = (*wHndl)->wFileInfo.sfr;
-
- if (!DisplayPutFile(&(reply)))
- return(userCanceledErr);
- /* User canceled the save. */
-
- if ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum != kInvalVRefNum) {
- if (err = CloseMovieFile((*wHndl)->wFileInfo.resFile) )
- DebugStr("\pCloseMovieFile failed in SaveMovie");
- /* Close the old file. Don't respond to any error here because
- ** the user may be trying to do a save-as because their old file
- ** is bad. If we fail to close the old file, and then respond
- ** to the error, the user won't get the opportunity to save
- ** their document to a new file.
- */
- }
- SetWTitle(FrontWindow(),reply.sfFile.name);
- (*wHndl)->wFileInfo.sfr = reply;
- if ( err = PutMovieToFile(wHndl, true) ) {
- reply.sfFile.vRefNum = kInvalVRefNum;
- DebugStr("\pCouldn't create the new file for save as");
- }
- }
- else /* saving into an existing file */
- if (err = PutMovieToFile(wHndl, false) ) {
- (*wHndl)->wFileInfo.sfr.sfFile.vRefNum = kInvalVRefNum;
- return(err);
- }
-
- ClearMovieChanged((*wHndl)->wMovie);
- return(noErr);
- }
-
-
- OSErr PutMovieToFile(wHndl, newFile)
- DocRecHandle wHndl;
- Boolean newFile;
- {
- OSErr theErr;
- short resFile,
- resID = 0; /* resource id = 0 tells the MovieToolbox to come up with a number */
- DialogPtr flattenDialog; /* the progress proc stores here its dialog pointer */
-
- /* we are about to save the file this is a good time to update the loop state both
- in memory and in the file.
-
- */
-
- UpdateLoopStateInfo(wHndl);
-
- UpdateWindowPos();
-
- resFile = CurResFile();
- if (newFile) {
- if ( gFlattenMovies) {
-
- /* Brackett Flatten movie with SetMovieProgress proc calls so that the user
- gets to know what is going on if the flattening takes too long.
- It is also important to lock the handle containing the movie reference,
- FlattenMovie moves data around and since we are dereferencing the handle
- the pointer we pass could end up pointing to garbage.
- */
- HLock((Handle)wHndl);
- SetMovieProgressProc((*wHndl)->wMovie, flattenProgressProc, (long) &flattenDialog);
-
- FlattenMovie((*wHndl)->wMovie, 0 /* flags */,
- &((*wHndl)->wFileInfo.sfr.sfFile), 'TVOD',0,
- createMovieFileDeleteCurFile /* createMovieFileFlags*/,
- &resID, nil /* resName */);
-
- HUnlock((Handle)wHndl);
- if (theErr = GetMoviesError())
- DebugStr("\pFlattenMovie failed");
- else
- (*wHndl)->wFileInfo.moovID = resID; /* remember the moov resource id */
-
- SetMovieProgressProc((*wHndl)->wMovie, nil, 0); /* flattening is done remove proc */
-
- if (theErr = OpenMovieFile( &((*wHndl)->wFileInfo.sfr.sfFile),
- &((*wHndl)->wFileInfo.resFile),fsRdWrPerm))
- DebugStr("\pOpenMovieFile failed");
- }
- else /* do not flatten */
- {
- if ( !(theErr = CreateMovieFile( &((*wHndl)->wFileInfo.sfr.sfFile), 'TVOD',0,createMovieFileDeleteCurFile,
- &((*wHndl)->wFileInfo.resFile), nil) )) {
- if (theErr = AddMovieResource((*wHndl)->wMovie, (*wHndl)->wFileInfo.resFile,
- &resID, nil /* resName */) )
- DebugStr("\pAddMovieResource failed in PutMovieToFile");
- else
- (*wHndl)->wFileInfo.moovID = resID; /* remember the moov resource id */
- }
- else DebugStr("\pCreateMovieFile Failed in PutMovieToFile");
- }
- }
- else
- if (theErr = UpdateMovieResource( (*wHndl)->wMovie, (*wHndl)->wFileInfo.resFile,
- (*wHndl)->wFileInfo.moovID, nil))
- DebugStr("\pPutMovieToFile: UpdateMovieResource failed");
-
- UseResFile(resFile);
- return (theErr);
- }